#!/usr/bin/env python
# -*- coding: utf-8 -*-
#=======================================#
# @author: RedSoxFan and NerfSoldier
# @copyright: 2012 RedSoxFan and NerfSoldier
# @license: GNU General Public License v3.0 
#           <http://www.gnu.org/copyleft/gpl.html>
# @summary: DarkDev ConfiG Parser
#=======================================#

#=======================================#
# Imports
#=======================================#
# Python
# DarkDev
from parsers import Parser
#=======================================#

class Ddcg(Parser):
    description = "DarkDev ConfiG"
    filefilter = "*.ddcg"
    key = "Ddcg"

class DDCGObject(object):
    def __init__(self,darkdev,fname=None):
        self.dd = darkdev
        self.__cfg = {}
        self.__fi = fname
    def __contains__(self,key):
        if "." in key: keys = key.split(".")
        else: keys = [key]
        v = self.__cfg
        for k in keys:
            if k:
                if k in v: v = v[k]
                else: return False
        return v!=self.__cfg
    def __getitem__(self,key):
        if "." in key: keys = key.split(".")
        else: keys = [key]
        v = self.__cfg
        for k in keys:
            if k:
                if k in v: v = v[k]
                else:
                    return {}
                    self.dd.logger.warning("DDCGObject: Key %r Not Found"%key)
        if v!=self.__cfg: return v
        else:
            return {}
            self.dd.logger.warning("DDCGObject: Key %r Not Found"%key)
    def __setitem__(self,key,value):
        if "." in key: keys = key.split(".")
        else: keys = [key]
        v = self.__cfg
        for k in keys[:-1]:
            if k:
                if k in v: v = v[k]
                else: v[k]={}; v = v[k]
        v[keys[-1]] = value
    def load(self,fname):
        f = open(fname,"r")
        key = ["","","",""]
        lines = f.read().split("\n")
        if lines[0].strip()!="# DarkDev ConfiG File": return False
        for l in lines[1:]:
            l = l.strip()
            if not(l) or l.startswith("#"): continue
            elif l.startswith("["): key=[l[1:-1],"","",""]
            elif l.startswith("<"): key=[key[0],l[1:-1],"",""]
            elif l.startswith("~"): key=[key[0],key[1],l[1:-1],""]
            else:
                key[3]=l[:l.find("=")].strip()
                val = l[l.find("=")+1:].strip()
                try:
                    self["%s.%s.%s.%s"%(key[0],key[1],key[2],key[3])]=eval(val)
                except:
                    self.dd.logger.warning("DDCGObject: Failed To Set Key %r To %r (Cannot Eval)"%(key,val))
        return True
    def save(self,fname=None):
        if not fname: fname = self.fname
        if fname:
            f = open(fname,"w")
            f.write("# DarkDev ConfiG File\r\n# Indentation is for readability and is NOT required\r\n\r\n")
            f.flush()
            for sec in sorted(self.__cfg.keys()):
                if isinstance(self[sec],dict):
                    f.write("[%s]\r\n"%sec)
                    f.flush()
                    for sub in sorted(self[sec].keys()):
                        if isinstance(self[sec][sub],dict):
                            f.write("\t<%s>\r\n"%sub)
                            f.flush()
                            for seg in sorted(self[sec][sub].keys()):
                                if isinstance(self[sec][sub][seg],dict):
                                    f.write("\t\t~%s~\r\n"%seg)
                                    f.flush()
                                    for key in sorted(self[sec][sub][seg].keys()):
                                        f.write("\t\t\t%s=%r\r\n"%(key,self["%s.%s.%s.%s"%(sec,sub,seg,key)]))
                                        f.flush()
                                else:
                                    f.write("\t\t%s=%r\r\n"%(seg,self["%s.%s.%s"%(sec,sub,seg)]))
                                    f.flush()
                        else:
                            f.write("\t%s=%r\r\n"%(sub,self["%s.%s"%(sec,sub)]))
                            f.flush()
                else:
                    f.write("%s=%r\r\n"%(sec,self["%s"%(sec)]))
                    f.flush()
            f.close()
    fname = property(fget=lambda self:self.__fi,fset=lambda self,f:self.load(f))